<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能知识库系统</title>
    <style>
        :root {
            --primary-color: #2c3e50;
            --secondary-color: #3498db;
            --success-color: #27ae60;
            --error-color: #e74c3c;
            --background-color: #f5f6fa;
            --text-color: #2c3e50;
            --card-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
        }

        body {
            background-color: var(--background-color);
            color: var(--text-color);
            min-height: 100vh;
        }

        .container {
            display: flex;
            height: 100vh;
            padding: 20px;
            gap: 20px;
        }

        /* 左侧边栏 */
        .sidebar {
            width: 30%;
            min-width: 300px;
            display: flex;
            flex-direction: column;
            gap: 20px;
        }

        .file-management {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: var(--card-shadow);
            height: calc(100vh - 40px);
            display: flex;
            flex-direction: column;
        }

        .upload-section {
            margin-bottom: 20px;
            position: relative;
        }

        #fileInput {
            display: none;
        }

        .custom-upload-btn {
            background-color: var(--secondary-color);
            color: white;
            padding: 12px 24px;
            border-radius: 4px;
            cursor: pointer;
            transition: opacity 0.2s;
            display: flex;
            align-items: center;
            gap: 8px;
            width: fit-content;
        }

        .file-list {
            flex: 1;
            overflow-y: auto;
            margin-top: 15px;
            border-top: 1px solid #eee;
            padding-top: 10px;
        }

        .file-item {
            padding: 12px;
            border-radius: 4px;
            background-color: #f8f9fa;
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: background-color 0.2s;
        }

        .delete-btn {
            background: none;
            border: none;
            color: var(--error-color);
            cursor: pointer;
        }

        /* 右侧主内容区 */
        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 20px;
        }

        .chat-section {
            flex: 1;
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: var(--card-shadow);
            display: flex;
            flex-direction: column;
        }

        .chat-history {
            flex: 1;
            overflow-y: auto;
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #eee;
            border-radius: 4px;
            scrollbar-width: thin;
            scrollbar-color: var(--secondary-color) #f1f1f1;
        }

        .chat-history::-webkit-scrollbar {
            width: 8px;
        }

        .chat-history::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }

        .chat-history::-webkit-scrollbar-thumb {
            background: var(--secondary-color);
            border-radius: 4px;
        }

        .message {
            margin: 10px 0;
            padding: 12px;
            border-radius: 6px;
            max-width: 85%;
            animation: fadeIn 0.3s ease-in;
            word-wrap: break-word;
        }

        .user-message {
            background-color: var(--primary-color);
            color: white;
            margin-left: auto;
        }

        .bot-message {
            background-color: #ecf0f1;
            margin-right: auto;
            position: relative;
        }

        .loading-indicator {
            display: none;
            align-items: center;
            gap: 8px;
            padding: 12px;
            color: #7f8c8d;
        }

        .loading-spinner {
            width: 16px;
            height: 16px;
            border: 2px solid #fff;
            border-top: 2px solid transparent;
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .input-group {
            display: flex;
            gap: 10px;
        }

        #questionInput {
            flex: 1;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
        }

        .ask-btn {
            background-color: var(--primary-color);
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .ask-btn:disabled {
            background-color: #95a5a6;
            cursor: not-allowed;
        }

        .status-message {
            position: fixed;
            bottom: 20px;
            right: 20px;
            padding: 12px 20px;
            border-radius: 4px;
            box-shadow: var(--card-shadow);
            display: none;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        code {
            background-color: #f1f2f6;
            padding: 2px 4px;
            border-radius: 3px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- 左侧文件管理 -->
        <div class="sidebar">
            <div class="file-management">
                <h2>📁 文件管理</h2>
                <div class="upload-section">
                    <label class="custom-upload-btn">
                        <span>📤 选择文件</span>
                        <input type="file" id="fileInput">
                    </label>
                    <button onclick="uploadFile()" class="ask-btn" style="margin-top:12px">
                        开始上传
                    </button>
                </div>
                <div class="file-list">
                    <h3>已上传文件</h3>
                    <div id="fileListItems">
                        {% for file in files %}
                        <div class="file-item">
                            <span>{{ file }}</span>
                            <button class="delete-btn" title="删除文件">🗑️</button>
                        </div>
                        {% endfor %}
                    </div>
                </div>
            </div>
        </div>

        <!-- 右侧问答区 -->
        <div class="main-content">
            <div class="chat-section">
                <h2>💬 智能问答</h2>
                <div class="chat-history" id="chatHistory">
                    <div class="loading-indicator" id="loadingIndicator">
                        <div class="loading-spinner"></div>
                        <span>思考中...</span>
                    </div>
                </div>
                <div class="input-group">
                    <input type="text" id="questionInput" placeholder="输入问题后按回车发送...">
                    <button onclick="askQuestion()" class="ask-btn" id="askButton">
                        发送
                    </button>
                </div>
            </div>
        </div>
    </div>

    <div class="status-message" id="statusMessage"></div>

    <script>
        let chatHistory = JSON.parse(localStorage.getItem('chatHistory')) || [];
        let isStreaming = false;
        let abortController = null;

        // 初始化
        document.addEventListener('DOMContentLoaded', () => {
            document.getElementById('questionInput').addEventListener('keypress', (e) => {
                if (e.key === 'Enter' && !isStreaming) askQuestion();
            });

            // 文件删除事件
            document.getElementById('fileListItems').addEventListener('click', (e) => {
                if (e.target.classList.contains('delete-btn')) {
                    const filename = e.target.previousElementSibling.textContent;
                    deleteFile(filename);
                }
            });
        });

        async function uploadFile() {
            const fileInput = document.getElementById('fileInput');
            if (!fileInput.files[0]) {
                showStatus('请先选择文件', 'error');
                return;
            }

            const formData = new FormData();
            formData.append('file', fileInput.files[0]);

            try {
                showStatus('文件上传中...', 'loading');
                const response = await fetch('/upload/', {
                    method: 'POST',
                    body: formData
                });

                if (response.ok) {
                    const data = await response.json();
                    addFileItem(data.filename);
                    showStatus('上传成功', 'success');
                    fileInput.value = '';
                }
            } catch (error) {
                showStatus(`上传失败: ${error.message}`, 'error');
            }
        }

        async function deleteFile(filename) {
            if (!confirm(`确定删除 ${filename} 吗？`)) return;

            try {
                showStatus('删除中...', 'loading');
                const response = await fetch(`/file/${filename}`, {
                    method: 'DELETE'
                });

                if (response.ok) {
                    document.querySelector(`button[onclick="deleteFile('${filename}')"]`)
                        .parentElement.remove();
                    showStatus('删除成功', 'success');
                }
            } catch (error) {
                showStatus(`删除失败: ${error.message}`, 'error');
            }
        }

        async function askQuestion() {
            if (isStreaming) {
                alert("请等待当前回答完成");
                return;
            }

            const input = document.getElementById('questionInput');
            const question = input.value.trim();
            if (!question) return;

            isStreaming = true;
            input.value = '';
            toggleLoading(true);

            const messageDiv = createMessageElement('');
            const loadingIndicator = document.getElementById('loadingIndicator');
            let answerContent = '';

            try {
                abortController = new AbortController();
                loadingIndicator.style.display = 'flex';

                const response = await fetch('/stream_ask/', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: `question=${encodeURIComponent(question)}`,
                    signal: abortController.signal
                });

                const reader = response.body.getReader();
                const decoder = new TextDecoder();

                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;

                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n').filter(line => line.trim());

                    for (const line of lines) {
                        try {
                            const data = JSON.parse(line);
                            if (data.end) break;

                            answerContent += data.content;
                            messageDiv.innerHTML = formatAnswer(answerContent);
                            scrollToBottom();
                        } catch (e) {
                            console.error('解析错误:', e);
                        }
                    }
                }

                saveHistory(question, answerContent);
            } catch (error) {
                if (error.name !== 'AbortError') {
                    answerContent += '（回答中断）';
                    messageDiv.innerHTML = answerContent;
                }
            } finally {
                isStreaming = false;
                toggleLoading(false);
                loadingIndicator.style.display = 'none';
                abortController = null;
            }
        }

        function createMessageElement(content) {
            const chatHistory = document.getElementById('chatHistory');
            const messageDiv = document.createElement('div');
            messageDiv.className = 'message bot-message';
            messageDiv.innerHTML = `<div class="message-content">${content}</div>`;
            chatHistory.appendChild(messageDiv);
            return messageDiv.querySelector('.message-content');
        }

        function formatAnswer(text) {
            return text
                .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
                .replace(/\*(.*?)\*/g, '<em>$1</em>')
                .replace(/`(.*?)`/g, '<code>$1</code>')
                .replace(/\n/g, '<br>');
        }

        function toggleLoading(show) {
            const button = document.getElementById('askButton');
            button.disabled = show;
            button.innerHTML = show
                ? `<div class="loading-spinner"></div> 发送中...`
                : `发送`;
        }

        function scrollToBottom() {
            const chatHistory = document.getElementById('chatHistory');
            chatHistory.scrollTop = chatHistory.scrollHeight;
        }

        function saveHistory(question, answer) {
            const record = {
                question,
                answer,
                timestamp: new Date().toLocaleString()
            };
            chatHistory.push(record);
            localStorage.setItem('chatHistory', JSON.stringify(chatHistory));
        }

        function showStatus(message, type) {
            const statusEl = document.getElementById('statusMessage');
            const colors = {
                success: '#27ae60',
                error: '#e74c3c',
                loading: '#2c3e50'
            };

            statusEl.textContent = message;
            statusEl.style.backgroundColor = colors[type] || '#2c3e50';
            statusEl.style.display = 'block';

            setTimeout(() => {
                statusEl.style.display = 'none';
            }, 3000);
        }
    </script>
</body>
</html>